#include "vector.h"

using namespace math_m;

Vector2D__m128::Vector2D__m128(){
	x = _mm_setzero_ps();
	y = _mm_setzero_ps();
};

Vector2D__m128::Vector2D__m128(const __m128 & _x,const __m128 & _y){
	x = _x;
	y = _y;
};

Vector2D__m128::Vector2D__m128(const Vector2D__m128 & vector){
	x = vector._x();
	y = vector._y();
};

__m128 Vector2D__m128::_x() const{
	return x;
};

__m128 Vector2D__m128::_y() const{
	return y;
};

__m128 Vector2D__m128::value() const{
	return _mm_sqrt_ps(_mm_add_ps(_mm_mul_ss(x,x),_mm_mul_ps(y,y)));
};

Vector2D__m128 Vector2D__m128::normalize() const{
	Vector2D__m128 _t(_mm_div_ps(x,value()),_mm_div_ps(y,value()));
	return _t;
};

Vector2D__m128 Vector2D__m128::operator + (const Vector2D__m128 & vector) const{
	Vector2D__m128 _t(_mm_add_ps(x,vector._x()),_mm_add_ps(y,vector._y()));
	return _t;
};

Vector2D__m128 Vector2D__m128::operator - (const Vector2D__m128 & vector) const{
	Vector2D__m128 _t(_mm_sub_ps(x,vector._x()),_mm_sub_ps(y,vector._y()));
	return _t;
};

Vector2D__m128 Vector2D__m128::operator * (const __m128 & value) const{
	Vector2D__m128 _t(_mm_mul_ps(x,value),_mm_mul_ps(y,value));
	return _t;
};

__m128 Vector2D__m128::operator * (const Vector2D__m128 & vector) const{
	return _mm_add_ss(_mm_mul_ps(x,vector._x()),_mm_mul_ps(y,vector._y()));
};

void Vector2D__m128::operator += (const Vector2D__m128 & vector){
	*this=*this+vector;
};

void Vector2D__m128::operator -= (const Vector2D__m128 & vector){
	*this=*this-vector;
};

void Vector2D__m128::operator *= (const __m128 & value){
	x = _mm_mul_ps(x,value);
	y = _mm_mul_ps(y,value);
};

void Vector2D__m128::operator = (const Vector2D__m128 & vector){
	x = vector._x();
	y = vector._y();
};

Vector2D__m128::~Vector2D__m128(){

};


Vector2D__m128d::Vector2D__m128d(){
	x = _mm_setzero_pd();
	y = _mm_setzero_pd();
};

Vector2D__m128d::Vector2D__m128d(const __m128d & _x,const __m128d & _y){
	x = _x;
	y = _y;
};

Vector2D__m128d::Vector2D__m128d(const Vector2D__m128d & vector){
	x = vector._x();
	y = vector._y();
};

__m128d Vector2D__m128d::_x() const{
	return x;
};

__m128d Vector2D__m128d::_y() const{
	return y;
};

__m128d Vector2D__m128d::value() const{
	return _mm_sqrt_pd(_mm_add_pd(_mm_mul_pd(x,x),_mm_mul_pd(y,y)));
};

Vector2D__m128d Vector2D__m128d::normalize() const{
	Vector2D__m128d _t(_mm_div_pd(x,value()),_mm_div_pd(y,value()));
	return _t;
};

Vector2D__m128d Vector2D__m128d::operator + (const Vector2D__m128d & vector) const{
	Vector2D__m128d _t(_mm_add_pd(x,vector._x()),_mm_add_pd(y,vector._y()));
	return _t;
};

Vector2D__m128d Vector2D__m128d::operator - (const Vector2D__m128d & vector) const{
	Vector2D__m128d _t(_mm_sub_pd(x,vector._x()),_mm_sub_pd(y,vector._y()));
	return _t;
};

Vector2D__m128d Vector2D__m128d::operator * (const __m128d & value) const{
	Vector2D__m128d _t(_mm_mul_pd(x,value),_mm_mul_pd(y,value));
	return _t;
};

__m128d Vector2D__m128d::operator * (const Vector2D__m128d & vector) const{
	return _mm_add_pd(_mm_mul_pd(x,vector._x()),_mm_mul_pd(y,vector._y()));
};

void Vector2D__m128d::operator += (const Vector2D__m128d & vector){
	*this=*this+vector;
};

void Vector2D__m128d::operator -= (const Vector2D__m128d & vector){
	*this=*this-vector;
};

void Vector2D__m128d::operator *= (const __m128d & value){
	x = _mm_mul_pd(x,value);
	y = _mm_mul_pd(y,value);
};

void Vector2D__m128d::operator = (const Vector2D__m128d & vector){
	x = vector._x();
	y = vector._y();
};

Vector2D__m128d::~Vector2D__m128d(){

};

Vector3D__m128::Vector3D__m128(){
	x = _mm_setzero_ps();
	y = _mm_setzero_ps();
	z = _mm_setzero_ps();
};

Vector3D__m128::Vector3D__m128(const __m128 & _x,const __m128 & _y,const __m128 & _z){
	x = _x;
	y = _y;
	z = _z;
};

Vector3D__m128::Vector3D__m128(const Vector3D__m128 & vector){
	x = vector._x();
	y = vector._y();
	z = vector._z();
};

__m128 Vector3D__m128::_x() const{
	return x;
};

__m128 Vector3D__m128::_y() const{
	return y;
};

__m128 Vector3D__m128::_z() const{
	return z;
};

__m128 Vector3D__m128::value() const{
	return _mm_sqrt_ps(_mm_add_ps(_mm_mul_ps(x,x),_mm_mul_ps(y,y)));
};

Vector3D__m128 Vector3D__m128::normalize() const{
	Vector3D__m128 _t(_mm_div_ps(x,value()),_mm_div_ps(y,value()),_mm_div_ps(z,value()));
	return _t;
};

Vector3D__m128 Vector3D__m128::operator + (const Vector3D__m128 & vector) const{
	Vector3D__m128 _t(_mm_add_ps(x,vector._x()),_mm_add_ps(y,vector._y()),_mm_add_ps(z,vector._z()));
	return _t;
};

Vector3D__m128 Vector3D__m128::operator - (const Vector3D__m128 & vector) const{
	Vector3D__m128 _t(_mm_sub_ps(x,vector._x()),_mm_sub_ps(y,vector._y()),_mm_sub_ps(z,vector._z()));
	return _t;
};

Vector3D__m128 Vector3D__m128::operator * (const __m128 & value) const{
	Vector3D__m128 _t(_mm_mul_ps(x,value),_mm_mul_ps(y,value),_mm_mul_ps(z,value));
	return _t;
};

__m128 Vector3D__m128::operator * (const Vector3D__m128 & vector) const{
	return _mm_add_ps(_mm_mul_ps(x,x),_mm_add_ps(_mm_mul_ps(y,y),_mm_mul_ps(z,z)));
};

Vector3D__m128 Vector3D__m128::operator ^ (const Vector3D__m128 & vector) const{
	Vector3D__m128 _t(_mm_sub_ps(_mm_mul_ps(y,vector._z()),_mm_mul_ps(z,vector._y())),
					  _mm_sub_ps(_mm_mul_ps(z,vector._x()),_mm_mul_ps(x,vector._z())),
					  _mm_sub_ps(_mm_mul_ps(x,vector._y()),_mm_mul_ps(y,vector._x())));
	return _t;
};

void Vector3D__m128::operator += (const Vector3D__m128 & vector){
	*this=*this+vector;
};

void Vector3D__m128::operator -= (const Vector3D__m128 & vector){
	*this=*this-vector;
};

void Vector3D__m128::operator *= (const __m128 & value){
	*this=*this*value;
};

void Vector3D__m128::operator ^= (const Vector3D__m128 & vector){
	*this=*this^vector;
};

void Vector3D__m128::operator = (const Vector3D__m128 & vector){
	x = vector._x();
	y = vector._y();
	z = vector._z();
};

Vector3D__m128::~Vector3D__m128(){

};